<template>
  <div ref="tableModuleRef" class="table-module">
    <!-- 操作栏 -->
    <div v-show="resetBtnDisplay" class="table-action">
      <el-popconfirm
        title="是否清空列表？"
        confirm-button-text="确认"
        cancel-button-text="取消"
        @confirm="handleRest"
      >
        <template #reference>
          <el-button text>清空列表</el-button>
        </template>
      </el-popconfirm>
      <el-pagination
        v-model:page-size="pageSize"
        v-model:current-page="currentPage"
        :pager-count="5"
        :total="total"
        hide-on-single-page
        layout="prev, pager, next, jumper"
      />
    </div>
    <!-- 表格 -->
    <div class="table-main">
      <el-table
        :data="curTableData"
        size="large"
        class="el-table"
        scrollbar-always-on
        show-overflow-tooltip
        :style="{ height: '100%' }"
        :cell-style="setCellStyle"
        border
        @cell-click="handleCellClick"
      >
        <el-table-column
          prop="original"
          label="原文件名"
          resizable
          :min-width="getColumnWidth('original')"
        >
          <template #default="{ row }">
            <div class="old-file-name">
              <component :is="defineAsyncComponent(loadFileIcon(row))" />
              <span class="text">{{ getOriginalFileName(row) }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column
          prop="newFileName"
          label="新文件名"
          resizable
          :min-width="getColumnWidth('newest')"
        >
          <template #default="{ row }">
            <template v-if="curEditCell === row.fullPath">
              <div class="new-file-oper">
                <el-input
                  v-model="row.newest.name"
                  size="small"
                  @blur="curEditCell = ''"
                />
                <template v-if="row.newest.ext">
                  {{ `.${getNewestFileNameExt(row)}` }}
                </template>
              </div>
            </template>
            <div
              v-show="curEditCell !== row.fullPath"
              class="new-file-display nowrap"
            >
              {{ getNewestFileName(row) }}
            </div>
          </template>
        </el-table-column>
        <el-table-column
          prop="path"
          label="文件路径"
          resizable
          :min-width="getColumnWidth('path')"
        />
        <el-table-column
          prop="status"
          label="状态"
          align="center"
          resizable
          min-width="120"
        >
          <template #default="{ row }">
            <el-tag :type="getStateType(row.state)" effect="light">
              {{ getStateText(row.state) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" resizable min-width="120">
          <template #default="{ row }">
            <div class="icon-oper">
              <el-tooltip content="删除" placement="bottom">
                <el-icon :size="18" @click="handleRemove(row.fullPath)">
                  <Delete />
                </el-icon>
              </el-tooltip>
              <el-divider direction="vertical" />
              <el-tooltip content="打开上级路径" placement="bottom">
                <el-icon :size="18" @click="handleOpenPath(row.path)">
                  <FolderOpened />
                </el-icon>
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script lang="ts" setup>
import useLoadCurTableData from './hooks/useLoadCurTableData'
import useCalculatePageSize from './hooks/useCalculatePageSize'
import useCalculateCell from './hooks/useCalculateCell'
import useLoadTableAction from './hooks/useLoadTableAction'
import useCalculateColumnWidth from './hooks/useCalculateColumnWidth'
import useLoadFileIcon from './hooks/useLoadFileIcon'
import { Delete, FolderOpened } from '@element-plus/icons-vue'
import { ElTag } from 'element-plus'
import { watch, ref, computed, onMounted, defineAsyncComponent } from 'vue'

const props = defineProps<{
  tableData: ITableDataItem[]
}>()

const emits = defineEmits(['reset', 'remove'])

const tableModuleRef = ref()

// 总数据量
const total = computed(() => props.tableData.length)
// 当前页数
const currentPage = ref(1)
// 当前页条数
const pageSize = ref(0)

// resize 事件触发
useCalculatePageSize(tableModuleRef, pageSize)

// 加载当前分页数据
const { curTableData, loadCurTableData } = useLoadCurTableData()

const { getColumnWidth, resetAntiShakeMap } =
  useCalculateColumnWidth(curTableData)

const {
  getOriginalFileName,
  getNewestFileName,
  getNewestFileNameExt,
  curEditCell,
  handleCellClick,
  getStateText,
  getStateType,
  setCellStyle
} = useCalculateCell()

const { handleOpenPath, handleRemove, handleRest } = useLoadTableAction(emits)

// 文件图标
const { loadFileIcon } = useLoadFileIcon()

onMounted(() => {
  // 加载对应的数据
  loadCurTableData(props.tableData, currentPage.value, pageSize.value)
})

watch(
  [() => props.tableData.length, () => currentPage.value, () => pageSize.value],
  () => {
    reload()
  }
)

// 重新加载表格数据
function reload() {
  // 数量发生变化时,清空防抖 Map
  resetAntiShakeMap()
  // 加载对应的数据
  loadCurTableData(props.tableData, currentPage.value, pageSize.value)
}

const resetBtnDisplay = computed(() => {
  return props.tableData.length > 0
})

defineExpose({
  reload
})
</script>

<style lang="less" scoped>
// 去除选中的样式
:deep(
    .el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell
  ) {
  background-color: #fff;
}

// 解决 el-table 不能动态改变宽度的问题: https://blog.csdn.net/honeymoon_/article/details/118361320
.table-module {
  height: 100%;
  margin: 0 -1px;

  .table-action {
    display: flex;
    justify-content: space-between;
    margin-bottom: 8px;
    padding: 0 16px;
  }

  .table-main {
    position: relative;
    // 减去 table-action 的高度
    height: calc(100% - 40px);

    .el-table {
      --el-table-border-color: var(--el-border-color);
      position: absolute;

      .old-file-name {
        display: flex;
        align-items: center;
      }

      // 图标调整
      .icon-oper {
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 19px;

        > :nth-child(n) {
          cursor: pointer;
        }
      }

      .new-file-oper {
        display: flex;
        justify-content: center;
      }

      .new-file-display {
        padding: 0 8px;
        border-radius: 8px;
        cursor: pointer;

        &:hover {
          background: #dfe4ea;
        }
      }
    }
  }
}
</style>
